using Microsoft.EntityFrameworkCore;
using Serilog;
using STD.Shared.Common.Extensions;
using STD.Services.UserService.Domain.Repositories;
using STD.Services.UserService.Infrastructure.Data;
using STD.Shared.Infrastructure.Database;
using STD.Shared.Infrastructure.Caching;
using STD.Shared.Infrastructure.Messaging;
using StackExchange.Redis;
using RabbitMQ.Client;
using Consul;
using Prometheus;

var builder = WebApplication.CreateBuilder(args);

// 配置Serilog
Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(builder.Configuration)
    .Enrich.FromLogContext()
    .WriteTo.Console()
    .WriteTo.File("logs/userservice-.txt", rollingInterval: RollingInterval.Day)
    .CreateLogger();

builder.Host.UseSerilog();

// 添加服务到容器
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// 添加共享服务
builder.Services.AddSharedServices(builder.Configuration);

// 配置数据库
var databaseProvider = builder.Services.BuildServiceProvider()
    .GetRequiredService<IDatabaseProvider>();
var connectionString = databaseProvider.GetConnectionString(builder.Configuration, "Database");

builder.Services.AddDbContext<UserDbContext>(options =>
{
    databaseProvider.ConfigureDbContext(options, connectionString);
});

// 注册仓储
builder.Services.AddScoped<IUserRepository, UserRepository>();

// 添加MediatR
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<Program>());

// 添加AutoMapper
builder.Services.AddAutoMapper(typeof(Program));

// 添加Redis
builder.Services.AddSingleton<IConnectionMultiplexer>(sp =>
{
    var redisConnection = builder.Configuration.GetConnectionString("Redis") ?? "localhost:6379";
    return ConnectionMultiplexer.Connect(redisConnection);
});

// 添加RabbitMQ
builder.Services.AddSingleton<IConnection>(sp =>
{
    var rabbitMqHost = builder.Configuration.GetValue<string>("RabbitMQ:Host") ?? "localhost";
    var factory = new ConnectionFactory { HostName = rabbitMqHost };
    return factory.CreateConnection();
});

builder.Services.AddSingleton<IMessageBus>(sp =>
{
    var connection = sp.GetRequiredService<IConnection>();
    return new RabbitMQMessageBus(connection);
});

// 添加Consul
builder.Services.AddSingleton<IConsulClient>(sp =>
{
    var consulHost = builder.Configuration.GetValue<string>("Consul:Host") ?? "localhost";
    var consulPort = builder.Configuration.GetValue<int>("Consul:Port", 8500);
    return new ConsulClient(c => c.Address = new Uri($"http://{consulHost}:{consulPort}"));
});

var app = builder.Build();

// 配置HTTP请求管道
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

// 启用Prometheus指标端点
app.UseMetricServer();
app.UseHttpMetrics();

// 健康检查
app.MapGet("/health", () => Results.Ok(new { Status = "Healthy", Service = "UserService" }));

// 注册到Consul
if (app.Environment.IsProduction())
{
    var consulClient = app.Services.GetRequiredService<IConsulClient>();
    var serviceId = $"userservice-{Environment.MachineName}";
    var serviceName = "userservice";
    var servicePort = builder.Configuration.GetValue<int>("Service:Port", 5001);
    var serviceAddress = builder.Configuration.GetValue<string>("Service:Address") ?? "localhost";

    var registration = new AgentServiceRegistration
    {
        ID = serviceId,
        Name = serviceName,
        Address = serviceAddress,
        Port = servicePort,
        Tags = new[] { "api", "users" },
        Check = new AgentServiceCheck
        {
            HTTP = $"http://{serviceAddress}:{servicePort}/health",
            Interval = TimeSpan.FromSeconds(10),
            Timeout = TimeSpan.FromSeconds(5)
        }
    };

    await consulClient.Agent.ServiceRegister(registration);
}

// 确保数据库已创建
using (var scope = app.Services.CreateScope())
{
    var context = scope.ServiceProvider.GetRequiredService<UserDbContext>();
    await context.Database.EnsureCreatedAsync();
}

Log.Information("UserService 启动完成");

app.Run(); 